package com.greet.service.impl;

import com.greet.constant.MessageConstant;
import com.greet.context.BaseContext;
import com.greet.dto.OrdersDTO;
import com.greet.dto.OrdersPageQueryDTO;
import com.greet.dto.OrdersPaymentDTO;
import com.greet.dto.OrdersSubmitDTO;
import com.greet.entity.AddressBook;
import com.greet.entity.OrderDetail;
import com.greet.entity.Orders;
import com.greet.entity.ShoppingCart;
import com.greet.exception.AddressBookBusinessException;
import com.greet.exception.ShoppingCartBusinessException;
import com.greet.mapper.AddressBookMapper;
import com.greet.mapper.OrderDetailMapper;
import com.greet.mapper.OrdersMapper;
import com.greet.mapper.ShoppingCartMapper;
import com.greet.result.PageResult;
import com.greet.service.OrderService;
import com.greet.utils.PojoTypeTranformationUtil;
import com.greet.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.TemporalUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrdersMapper ordersMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) {
        //处理各种业务异常(地址簿为空， 购物车数据为空)
        List<AddressBook> addressBooks = addressBookMapper.select(
                AddressBook.builder().id(ordersSubmitDTO.getAddressBookId()).build()
        );
        if (addressBooks == null || addressBooks.isEmpty())
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        List<ShoppingCart> shoppingCarts = shoppingCartMapper.select(
                ShoppingCart.builder().userId(BaseContext.getCurrentId()).build()
        );
        if (shoppingCarts == null || shoppingCarts.isEmpty())
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        //向订单插入一条数据
        Orders orders = new Orders();
        BeanUtils.copyProperties(ordersSubmitDTO, orders);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setPhone(addressBooks.get(0).getPhone());
        orders.setConsignee(addressBooks.get(0).getConsignee());
        orders.setUserId(BaseContext.getCurrentId());
        orders.setAddress(
                addressBooks.get(0).getCityName() + " "
                + addressBooks.get(0).getDistrictName()
                + addressBooks.get(0).getDetail()
                );
        orders.setTablewareNumber(ordersSubmitDTO.getTablewareNumber());
        ordersMapper.insert(orders);
        Long orderId = orders.getId();
        //向订单明细插入n条数据
        List<OrderDetail> orderDetailList = new ArrayList<>(30);
        for (ShoppingCart shoppingCart : shoppingCarts){
            OrderDetail tmp = OrderDetail.builder().name(shoppingCart.getName())
                    .orderId(orderId)
                    .dishId(shoppingCart.getDishId())
                    .setmealId(shoppingCart.getSetmealId())
                    .dishFlavor(shoppingCart.getDishFlavor())
                    .number(shoppingCart.getNumber())
                    .amount(shoppingCart.getAmount())
                    .image(shoppingCart.getImage()).build();
            orderDetailList.add(tmp);
        }
        orderDetailMapper.insertBatch(orderDetailList);

        //清空当前用户购物车数据
        shoppingCartMapper.deleteByUserId(BaseContext.getCurrentId());

        //返回OrdersSubmitVO对象
        OrderSubmitVO result = OrderSubmitVO.builder().id(orderId)
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime()).build();
        return result;
    }

    @Override
    public Long payment(OrdersPaymentDTO paymentDTO) {
        Orders orders = Orders.builder()
                .number(paymentDTO.getOrderNumber())
                .payMethod(paymentDTO.getPayMethod())
                .status(2)
                .checkoutTime(LocalDateTime.now())
                .payStatus(1).build();
        ordersMapper.updateByNumber(orders);
        orders = ordersMapper.selectByNumber(orders.getNumber());
        return orders.getId();
    }

    @Override
    public OrderVO getById(Long id) {
        //查询orders复制给OrdersHistoryVO
        Orders orders = ordersMapper.selectById(id);
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        //查询订单详细信息给ordersDTO
        List<OrderDetail> orderDetailList =  orderDetailMapper.selecListByOrdersId(id);
        orderVO.setOrderDetailList(orderDetailList);

        return orderVO;

    }

    @Override
    public PageResult historyOrders(OrdersPageQueryDTO ordersPageQueryDTO) {
        //计算UserId的历史订单数量
        Long tatol = ordersMapper.countByUser(ordersPageQueryDTO.getUserId());

        List<Orders> ordersList = ordersMapper.selectPageQuery(ordersPageQueryDTO);
        List<OrdersHistoryVO> ordersHistoryVOList = new ArrayList<>();
        for (Orders orders : ordersList){
            OrdersHistoryVO ordersHistoryVO = new OrdersHistoryVO();
            BeanUtils.copyProperties(orders, ordersHistoryVO);
            List<OrderDetail> orderDetailList = orderDetailMapper.selecListByOrdersId(orders.getId());
            ordersHistoryVO.setOrderDetailList(orderDetailList);

            ordersHistoryVOList.add(ordersHistoryVO);
        }
        return new PageResult(tatol, ordersHistoryVOList);

    }

    @Override
    public void repetition(Long id) {
        Orders orders = ordersMapper.selectById(id);
        List<OrderDetail> orderDetailList = orderDetailMapper.selecListByOrdersId(id);

        orders.setId(null);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setStatus(Orders.TO_BE_CONFIRMED);
        orders.setPayStatus(Orders.PAID);
        orders.setCheckoutTime(LocalDateTime.now());
        orders.setPayMethod(1);
        orders.setEstimatedDeliveryTime(LocalDateTime.now().plusHours(1l));
        orders.setOrderTime(LocalDateTime.now());
        orders.setDeliveryTime(null);

        ordersMapper.insert(orders);
        Long ordersId = orders.getId();
        for (OrderDetail orderDetail : orderDetailList){
            orderDetail.setOrderId(ordersId);
            orderDetail.setId(null);
        }
        orderDetailMapper.insertBatch(orderDetailList);

    }

    @Override
    public void cancel(Long id) {
        ordersMapper.updateCancel(
                Orders.builder().id(id)
                        .status(Orders.CANCELLED).build()
        );
    }

    @Override
    public void cancel(Orders orders) {
        orders.setStatus(Orders.CANCELLED);
        ordersMapper.updateCancel(orders);
    }

    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
        int index = ordersPageQueryDTO.getPage();
        index = (index - 1) * ordersPageQueryDTO.getPageSize();
        ordersPageQueryDTO.setPage(index);
        List<Orders> ordersList = ordersMapper.selectPageQuery(ordersPageQueryDTO);
        List<OrderSimplicityDetailVO> voList = new ArrayList<>();
        //将orders转换成OrderSimplicityDetailVO
        for (Orders orders : ordersList){
            OrderSimplicityDetailVO orderVo = new OrderSimplicityDetailVO();
            BeanUtils.copyProperties(orders, orderVo);
            Long orderId = orderVo.getId();
            //将订单详细处理成字符串
            List<OrderDetail> orderDetailList = orderDetailMapper.selecListByOrdersId(orderId);
            String voDetail = new String("");
            for (int i = 0; i < orderDetailList.size(); ++i){
                if (i != 0)voDetail = voDetail + ",";
                OrderDetail detail = orderDetailList.get(i);
                voDetail = voDetail + detail.getName();
                String dishFlavor = detail.getDishFlavor();
                if (dishFlavor != null && dishFlavor != ""){
                    voDetail = voDetail + "(" + dishFlavor + ")";
                }
            }
            orderVo.setOrderDishes(voDetail);

            //将orderVo加入返回的数据中
            voList.add(orderVo);
        }
        //统计订单
        Long total = ordersMapper.countAll();
        return new PageResult(total, voList);
    }

    @Override
    public OrderStatisticsVO statistics() {
        LocalDateTime begin = LocalDateTime.of(2000, 1, 1, 0, 0, 0);
        LocalDateTime end = LocalDateTime.now();
        Integer confirmed = ordersMapper.countByStatus(begin, end, Orders.CONFIRMED);//查询待派送
        Integer deliveryInProgress = ordersMapper.countByStatus(begin, end, Orders.DELIVERY_IN_PROGRESS);//查询派送中
        Integer toBeConfirmed = ordersMapper.countByStatus(begin, end, Orders.TO_BE_CONFIRMED);//待接单数量
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        orderStatisticsVO.setConfirmed(confirmed);
        orderStatisticsVO.setDeliveryInProgress(deliveryInProgress);
        orderStatisticsVO.setToBeConfirmed(toBeConfirmed);
        return orderStatisticsVO;
    }

    @Override
    public void confirm(Long id) throws Exception {
        Orders orders = ordersMapper.selectById(id);
        if (orders == null || orders.getStatus().intValue() == Orders.CANCELLED)throw new Exception("用户已经取消订单!");
        ordersMapper.updateStatus(id, Orders.CONFIRMED);
    }

    @Override
    public void delivery(Long id) {
        ordersMapper.updateStatus(id, Orders.DELIVERY_IN_PROGRESS);
    }

    @Override
    public void rejection(Orders orders) throws Exception {
        Orders o = ordersMapper.selectById(orders.getId());
        if (o.getStatus().intValue() == Orders.CANCELLED)throw new Exception("用户已经取消订单!");

        orders.setStatus(Orders.CANCELLED);
        orders.setCancelTime(LocalDateTime.now());

        orders.setCancelReason("商家拒绝订单");
        ordersMapper.updateCancel(orders);
    }

    @Override
    public void complete(Long id) {
        ordersMapper.updateStatus(id, Orders.COMPLETED);
    }

}
